'''
KamitKami gives a smaller css to be included with html file for faster website loading times.
Copyright (C) 2021 Sagar Acharya

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
'''

import sys, os, re
from bs4 import BeautifulSoup
from scrapy.selector import Selector 
from scrapy.http import HtmlResponse

# changes working directory to script directory
os.chdir(os.getcwd())

# get arguments from terminal to list
names = sys.argv[1:]

# list which keeps some attributes as they are within css file
nofilter = ["*", "html", "body", ":root", "head"]

# checks whether number of arguments are correct
if len(names)!=2:
	print("Please input only 2 arguments, css filename and html filename")
	sys.exit()

with open(names[0]+'.css') as temp:
	css = temp.read()
with open(names[1]+'.html') as temp:
	html = temp.read()

def divide_elem_blocks(css_string):
	_import = ["@import" + x + ";" for x in re.findall(r'@import(.*?);', css_string)]
	for i in _import:
		css_string = css_string.replace(i, "")
	
	selectors = []
	blocks = []
	num_curly = 0
	start = False
	
	record = ["", ""]
	for i in css_string:
		if start:
			if (i == '{'):
				num_curly +=1
				record[1] +=i
			elif (i == '}' and num_curly == 0):
				selectors.append(record[0])
				blocks.append(record[1])
				record = ["", ""]
				start = False
			elif (i == '}' and num_curly > 0):
				num_curly -=1				
			else:
				record[1]+=i
		else:
			if (i == '{'):
				start = True
			else:
				record[0]+=i

		if (i == '{' and num_curly == 0):
			start = True

	return _import, selectors, blocks

# filters C type comments
css = re.sub('\/\*(\*(?!\/)|[^*])*\*\/', '', css)
css = css.replace("\n", "")

# selectors and blocks have same length and correspond to each other
_import, selectors, blocks = divide_elem_blocks(css)

#Scrapy used here to check if a particular css selector is used in html
response = HtmlResponse(url = 'http://mysite.com', body = html,encoding='utf-8')
print(response.css('card-container').get()==None)

def check_css_in_html(response,selector):
	try:
		if response.css(selector).get()!=None:
			return True
	except:pass
	return False

# filters innermost content between { & }
#css = re.sub('\{[^{}]*\}', '', css)
#css = re.sub('\{[^{}]*\}', '', css)

# skip everything till next comment, take html variable as input and using python-scrapy, find relevant css here, change things at if statement at end

soup = BeautifulSoup(html, 'html.parser')

classes = []
tags = []
type_elem = []
for i in soup.find_all(True):
	tags.append(i.name)

	try:
		for j in i.attrs['class']:
			classes.append('.'+j)
	except:
		pass

	try:
		type_elem.append('[type="'+i.attrs['type']+'"')
	except:
		pass

#found unique list of tags, classes, types used in document (id yet to do)
classes = list(set(classes))
tags = [e for e in list(set(tags)) if e not in ('br', 'meta', 'div', 'link', 'html', 'body', 'head')]
type_elem = list(set(type_elem))

#keep all selectors:blocks of nofilter list

# https://www.w3schools.com/cssref/css_selectors.asp
# Find relevant css tags and according to above formatting,
# filter irrelevant ones and write keys:blocks to file below.

# class,class .class.class
# [hidden]
# :: , :
# [type="class"]
# :hover, active, etc.
# [^=] [*=]
# :not(:something)

with open(names[1]+"_"+names[0]+".css", 'w') as f:
	for i in _import:
		f.write(i)
	for i in selectors:
		#we split the selectors into individual and check them in html
		selector = i.split(',')
		for sel in selector:
			if (check_css_in_html(response,sel)):
				#if even one selector is present in html then we put entry into the output css
				print(i+" selected")
				f.write(i)
				f.write('{')
				f.write(blocks[selectors.index(i)])
				f.write("}\n")
				break

#minify
